// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_file_system.h"
#include "mk_engine.h"
#include "mk_log.h"
#include "mk_error.h"

namespace MK3DE
{
	CFileSystem::CFileSystem()
	{

	}

	CFileSystem::~CFileSystem()
	{
		Destroy();
	}

	BOOL CFileSystem::Create()
	{
		return TRUE;
	}

	BOOL CFileSystem::Destroy()
	{
		std::vector<CPackBase*>::iterator i = _vecPack.begin();
		while (i != _vecPack.end())
		{
			CPackBase* pack = *i;
			pack->Destroy();
			SAFE_DELETE(pack);

			++i;
		}

		_vecPack.clear();
		return TRUE;
	}

	void CFileSystem::SetRoot(const char* root)
	{
		_root = root;
	}

	BOOL CFileSystem::AddPack(const char* packName, FILE_PACK_TYPE type)
	{
		switch (type)
		{
		case FPT_ZIP:
			{
				CPackZip* pack = new CPackZip();
				if (!pack->Create(packName))
				{
					GetEngine()->GetLog()->Write(MKLT_ERROR, "Create pack failed[name: %s, type: %d]", packName, type);
					delete(pack);
					return FALSE;
				}

				_vecPack.push_back(pack);
			}
			break;

		default:
			GetEngine()->GetLog()->Write(MKLT_ERROR, "Unsupported file pack type: %d", type);
			return FALSE;
		}

		return TRUE;
	}

	BOOL CFileSystem::ReadFile(const char* fileName, CMemoryBlock* block)
	{
		std::vector<CPackBase*>::iterator i = _vecPack.begin();
		while (i != _vecPack.end())
		{
			CPackBase* pack = *i;
			if (pack->ReadFile(fileName, block))
				return TRUE;

			++i;
		}

		BOOL ret = FALSE;
		size_t r_len = 0;
		std::string fullPath = _root + fileName;
		FILE* fp = fopen(fullPath.c_str(), "rb");
		MK_PROCESS_ERROR(fp);

		DWORD len = __NativeFileLen(fp);
		ret = block->Alloc(len);
		MK_PROCESS_ERROR(ret);

		r_len = fread(block->GetBuffer(), 1, len, fp);
		MK_PROCESS_ERROR(r_len == len);

		fclose(fp);

		ret = TRUE;
Exit0:
		return ret;
	}

	DWORD CFileSystem::__NativeFileLen(FILE* fp)
	{
		fseek(fp, 0, SEEK_END);
		DWORD len = (DWORD)ftell(fp);
		fseek(fp, 0, SEEK_SET);
		return len;
	}
}